﻿2026-08-01T18:03:36.3299260Z ##[group]Run set -euo pipefail
2026-08-01T18:03:36.3299717Z [36;1mset -euo pipefail[0m
2026-08-01T18:03:36.3300088Z [36;1mmkdir -p /tmp/financemanager-phase3-backend/runtime[0m
2026-08-01T18:03:36.3300673Z [36;1mpython -m pytest tests -q | tee /tmp/financemanager-phase3-backend/pytest.log[0m
2026-08-01T18:03:36.3301388Z [36;1mpassed_count=$(sed -nE 's/.*(^|[^0-9])([0-9]+) passed.*/\2/p' /tmp/financemanager-phase3-backend/pytest.log | tail -n 1)[0m
2026-08-01T18:03:36.3301951Z [36;1mtest -n "${passed_count}"[0m
2026-08-01T18:03:36.3302314Z [36;1mtest "${passed_count}" -ge 667[0m
2026-08-01T18:03:36.3332766Z shell: /usr/bin/bash --noprofile --norc -e -o pipefail {0}
2026-08-01T18:03:36.3333210Z env:
2026-08-01T18:03:36.3333512Z   PYTHONPATH: src
2026-08-01T18:03:36.3333831Z   JARVIS_FINANCE_ENV: test
2026-08-01T18:03:36.3334659Z   JARVIS_FINANCE_DB_PATH: /tmp/financemanager-phase3-backend/finance.sqlite3
2026-08-01T18:03:36.3335242Z   JARVIS_FINANCE_RUNTIME_DIR: /tmp/financemanager-phase3-backend/runtime
2026-08-01T18:03:36.3335837Z   JARVIS_FINANCE_WRITE_MODE: disabled
2026-08-01T18:03:36.3336260Z   pythonLocation: /opt/hostedtoolcache/Python/3.11.15/x64
2026-08-01T18:03:36.3336733Z   PKG_CONFIG_PATH: /opt/hostedtoolcache/Python/3.11.15/x64/lib/pkgconfig
2026-08-01T18:03:36.3337205Z   Python_ROOT_DIR: /opt/hostedtoolcache/Python/3.11.15/x64
2026-08-01T18:03:36.3337698Z   Python2_ROOT_DIR: /opt/hostedtoolcache/Python/3.11.15/x64
2026-08-01T18:03:36.3338126Z   Python3_ROOT_DIR: /opt/hostedtoolcache/Python/3.11.15/x64
2026-08-01T18:03:36.3338686Z   LD_LIBRARY_PATH: /opt/hostedtoolcache/Python/3.11.15/x64/lib
2026-08-01T18:03:36.3339082Z ##[endgroup]
2026-08-01T18:03:57.0586638Z ......................................................................F. [  8%]
2026-08-01T18:04:10.2353645Z ........................................................................ [ 16%]
2026-08-01T18:04:22.9026446Z ........................................................................ [ 24%]
2026-08-01T18:04:48.2348740Z ........................................................................ [ 32%]
2026-08-01T18:05:04.5505888Z ........................................................................ [ 41%]
2026-08-01T18:05:15.7021200Z .........................F.............................................. [ 49%]
2026-08-01T18:05:27.5047842Z ........................................................................ [ 57%]
2026-08-01T18:05:45.8786660Z ........................................................................ [ 65%]
2026-08-01T18:06:00.7513883Z ........................................................................ [ 73%]
2026-08-01T18:06:25.6511391Z ........................................................................ [ 82%]
2026-08-01T18:06:49.0321682Z ........................................................................ [ 90%]
2026-08-01T18:07:03.6033507Z ........................................................................ [ 98%]
2026-08-01T18:07:08.4445673Z ............                                                             [100%]
2026-08-01T18:07:08.4447302Z =================================== FAILURES ===================================
2026-08-01T18:07:08.4448304Z _ test_changed_analytics_and_category_contracts_expose_partial_financial_data __
2026-08-01T18:07:08.4449079Z 
2026-08-01T18:07:08.4449515Z budget_reference_date = ReferenceDate(2026, 5, 31)
2026-08-01T18:07:08.4450145Z 
2026-08-01T18:07:08.4450743Z     def test_changed_analytics_and_category_contracts_expose_partial_financial_data(
2026-08-01T18:07:08.4452087Z         budget_reference_date,
2026-08-01T18:07:08.4452858Z     ) -> None:
2026-08-01T18:07:08.4453455Z         conn = db()
2026-08-01T18:07:08.4454319Z         account, food, _, _ = seed_budget(conn)
2026-08-01T18:07:08.4455182Z         confirm_budget_transaction(conn, {
2026-08-01T18:07:08.4455977Z             "account_id": account,
2026-08-01T18:07:08.4456771Z             "transaction_type": "expense",
2026-08-01T18:07:08.4457595Z             "transaction_date": "2026-05-20",
2026-08-01T18:07:08.4458838Z             "description": "Synthetic missing FX",
2026-08-01T18:07:08.4459658Z             "amount_original": "50.00",
2026-08-01T18:07:08.4460365Z             "currency_original": "EUR",
2026-08-01T18:07:08.4461144Z             "category_id": food,
2026-08-01T18:07:08.4461804Z         })
2026-08-01T18:07:08.4462363Z     
2026-08-01T18:07:08.4463147Z         cockpit = get_budget_dashboard_cockpit(conn, month="2026-05")
2026-08-01T18:07:08.4464238Z         assert cockpit["data_status"] == "partial"
2026-08-01T18:07:08.4465301Z         assert cockpit["unavailable_chf_count"] == 1
2026-08-01T18:07:08.4466282Z         assert cockpit["warnings"][0]["code"] == "missing_chf_conversion"
2026-08-01T18:07:08.4467255Z     
2026-08-01T18:07:08.4468014Z         analysis = get_budget_vs_actual_analysis(conn, year="2026")
2026-08-01T18:07:08.4468942Z         assert analysis["data_status"] == "partial"
2026-08-01T18:07:08.4469820Z         assert analysis["unavailable_chf_count"] == 1
2026-08-01T18:07:08.4470803Z         assert analysis["warnings"][0]["code"] == "missing_chf_conversion"
2026-08-01T18:07:08.4471788Z         assert analysis["totals"]["data_status"] == "partial"
2026-08-01T18:07:08.4472706Z     
2026-08-01T18:07:08.4473360Z         categories = get_category_summary(conn, "2026-05")
2026-08-01T18:07:08.4474351Z         assert categories["categories"] == []
2026-08-01T18:07:08.4475210Z         assert categories["data_status"] == "partial"
2026-08-01T18:07:08.4476085Z         assert categories["unavailable_chf_count"] == 1
2026-08-01T18:07:08.4477410Z         assert categories["warnings"][0]["code"] == "missing_chf_conversion"
2026-08-01T18:07:08.4478346Z     
2026-08-01T18:07:08.4479352Z         status_row = next(row for row in get_budget_status_by_category(conn, year="2026") if row["category_id"] == food)
2026-08-01T18:07:08.4480722Z         assert status_row["actual_current_month"] == "0.00"
2026-08-01T18:07:08.4481672Z         assert status_row["actual_year_to_date"] == "0.00"
2026-08-01T18:07:08.4482641Z >       assert status_row["forecast_year"] == "0.00"
2026-08-01T18:07:08.4483464Z E       AssertionError: assert '100.00' == '0.00'
2026-08-01T18:07:08.4484395Z E         
2026-08-01T18:07:08.4485055Z E         - 0.00
2026-08-01T18:07:08.4485638Z E         + 100.00
2026-08-01T18:07:08.4486276Z E         ? ++
2026-08-01T18:07:08.4486650Z 
2026-08-01T18:07:08.4487214Z tests/unit/test_budget_analytics_dashboard_v2.py:164: AssertionError
2026-08-01T18:07:08.4488451Z _____ test_integrations_dashboard_budgetplanning_and_data_explorer_fields ______
2026-08-01T18:07:08.4489341Z 
2026-08-01T18:07:08.4489992Z     def test_integrations_dashboard_budgetplanning_and_data_explorer_fields() -> None:
2026-08-01T18:07:08.4491188Z         conn = db(); account, media, _food, _insurance = setup(conn)
2026-08-01T18:07:08.4493210Z         preview = preview_manual_recurring_payment(conn, {"name": "Netflix", "category_id": media, "expected_amount_text": "20.00", "frequency": "monthly", "recurring_type": "subscription", "expected_day_of_month": 5})
2026-08-01T18:07:08.4495560Z         confirm_manual_recurring_payment(conn, preview["payload"])
2026-08-01T18:07:08.4496578Z         tx(conn, account, media, "Netflix", "20.00", "2026-02-05")
2026-08-01T18:07:08.4497476Z     
2026-08-01T18:07:08.4498100Z         dash = get_recurring_dashboard(conn, today="2026-03-01")
2026-08-01T18:07:08.4498991Z         assert dash["analytics"]["fixed_cost_quote_percent"] is not None
2026-08-01T18:07:08.4499856Z         assert dash["analytics"]["subscriptions_year_chf"] == "240.00"
2026-08-01T18:07:08.4500672Z         assert dash["kpis"]["monthly_fixed_costs_chf"] == "20.00"
2026-08-01T18:07:08.4501484Z         assert dash["kpis"]["annual_fixed_costs_chf"] == "240.00"
2026-08-01T18:07:08.4502226Z         assert dash["kpis"]["active_recurring_count"] == 1
2026-08-01T18:07:08.4502974Z         assert dash["kpis"]["open_candidate_count"] == 0
2026-08-01T18:07:08.4503810Z         assert dash["kpis"]["largest_fixed_costs"][0]["name"] == "Netflix"
2026-08-01T18:07:08.4505184Z         assert dash["category_breakdown"][0]["known_recurring_month_chf"] == "20.00"
2026-08-01T18:07:08.4506206Z     
2026-08-01T18:07:08.4506971Z         from jarvis_finance.services.budget_planning import get_budget_planning_matrix
2026-08-01T18:07:08.4508167Z         row = next(r for r in get_budget_planning_matrix(conn, year="2026", current_month="2026-02")["rows"] if r["category_id"] == media)
2026-08-01T18:07:08.4509330Z >       assert row["known_recurring_month_chf"] == "20.00"
2026-08-01T18:07:08.4509985Z E       AssertionError: assert '0.00' == '20.00'
2026-08-01T18:07:08.4510609Z E         
2026-08-01T18:07:08.4511088Z E         - 20.00
2026-08-01T18:07:08.4511622Z E         ? -
2026-08-01T18:07:08.4512120Z E         + 0.00
2026-08-01T18:07:08.4512472Z 
2026-08-01T18:07:08.4512879Z tests/unit/test_fixed_costs_subscriptions_v1.py:246: AssertionError
2026-08-01T18:07:08.4513724Z =============================== warnings summary ===============================
2026-08-01T18:07:08.4514979Z ../../../../../opt/hostedtoolcache/Python/3.11.15/x64/lib/python3.11/site-packages/fastapi/testclient.py:1
2026-08-01T18:07:08.4516770Z   /opt/hostedtoolcache/Python/3.11.15/x64/lib/python3.11/site-packages/fastapi/testclient.py:1: StarletteDeprecationWarning: Using `httpx` with `starlette.testclient` is deprecated; install `httpx2` instead.
2026-08-01T18:07:08.4518361Z     from starlette.testclient import TestClient as TestClient  # noqa
2026-08-01T18:07:08.4518922Z 
2026-08-01T18:07:08.4519427Z -- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
2026-08-01T18:07:08.4520453Z =========================== short test summary info ============================
2026-08-01T18:07:08.4521941Z FAILED tests/unit/test_budget_analytics_dashboard_v2.py::test_changed_analytics_and_category_contracts_expose_partial_financial_data - AssertionError: assert '100.00' == '0.00'
2026-08-01T18:07:08.4523207Z   
2026-08-01T18:07:08.4523701Z   - 0.00
2026-08-01T18:07:08.4524434Z   + 100.00
2026-08-01T18:07:08.4524961Z   ? ++
2026-08-01T18:07:08.4526182Z FAILED tests/unit/test_fixed_costs_subscriptions_v1.py::test_integrations_dashboard_budgetplanning_and_data_explorer_fields - AssertionError: assert '0.00' == '20.00'
2026-08-01T18:07:08.4527448Z   
2026-08-01T18:07:08.4527925Z   - 20.00
2026-08-01T18:07:08.4528418Z   ? -
2026-08-01T18:07:08.4528899Z   + 0.00
2026-08-01T18:07:08.4529527Z 2 failed, 874 passed, 1 warning in 211.12s (0:03:31)
2026-08-01T18:07:08.6437247Z ##[error]Process completed with exit code 1.
